/*
 * Copyright 2019 xiaomaoguai.com All right reserved. This software is the
 * confidential and proprietary information of xiaomaoguai.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with xiaomaoguai.com.
 */

package com.xiaomaoguai.core.next.hsf.http.annotation;

import com.xiaomaoguai.core.next.hsf.http.HsfHttpRequestProxy;
import com.xiaomaoguai.core.next.hsf.http.HsfHttpRequestScannerConfigurer;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

/**
 * 使用注解扫描HSF接口并注册，用于快速配置需要使用HTTP请求的HSF接口，下面演示几种使用方法（不代表全部）：
 *
 * <pre>
 *    &#064;Configuration
 *    &#064;HsfHttpRequestScan(basePackages = "com.xiaomaoguai.cdc", hsfHttpRequestProxyBeanName = "hsfHttpRequestProxy")
 *    public class Config() {
 *    }
 * </pre>
 *
 * or
 *
 * <pre>
 *    &#064;Configuration
 *    &#064;HsfHttpRequestScan(basePackages = "com.xiaomaoguai.cdc", restTemplateBeanName = "restTemplate4OkHttp3", serviceVersion = "${HSF.version.cdcService}", serverUrl = "${HSF.serverUrl.cdcService}")
 *    public class Config() {
 *    }
 * </pre>
 *
 * @author chenyao
 * @since 2016年8月30日 上午10:28:18
 * @see HsfHttpRequestScannerRegistrar
 * @see HsfHttpRequestScannerConfigurer
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(HsfHttpRequestScannerRegistrar.class)
public @interface HsfHttpRequestScan {
    /**
     * Alias for the {@link #basePackages()} attribute. Allows for more concise
     * annotation declarations e.g.: {@code @HsfHttpRequestScan("org.my.pkg")}
     * instead of {@code @HsfHttpRequestScan(basePackages= "org.my.pkg"})}.
     *
     * @return Base packages to scan for HSF interfaces
     */
    String[] value() default {};

    /**
     * Base packages to scan for HSF interfaces. Note that only interfaces with
     * at least one method will be registered; concrete classes will be ignored.
     *
     * @return Base packages to scan for HSF interfaces
     */
    String[] basePackages() default {};

    /**
     * Type-safe alternative to {@link #basePackages()} for specifying the
     * packages to scan for annotated components. The package of each class
     * specified will be scanned.
     * <p>
     * Consider creating a special no-op marker class or interface in each
     * package that serves no purpose other than being referenced by this
     * attribute.
     *
     * @return Base packages class to scan for HSF interfaces
     */
    Class<?>[] basePackageClasses() default {};

    /**
     * The {@link BeanNameGenerator} class to be used for naming detected
     * components within the Spring container.
     *
     * @return Strategy interface for generating bean names for bean definitions
     */
    Class<? extends BeanNameGenerator> beanNameGenerator() default BeanNameGenerator.class;

    /**
     * Bean Name的前缀
     *
     * @return 设置 Bean Name 的前缀，需要配合
     *         {@link app.myoss.cloud.core.spring.support.PrefixOrSuffixBeanNameGenerator}
     */
    String beanNamePrefix() default "";

    /**
     * Bean Name的后缀
     *
     * @return 设置 Bean Name 的后缀，需要配合
     *         {@link app.myoss.cloud.core.spring.support.PrefixOrSuffixBeanNameGenerator}
     */
    String beanNameSuffix() default "";

    /**
     * This property specifies the annotation that the scanner will search for.
     * <p>
     * The scanner will register all interfaces in the base package that also
     * have the specified annotation.
     * <p>
     * Note this can be combined with markerInterface.
     *
     * @return 使用注解过滤要扫描的class
     */
    Class<? extends Annotation> annotationClass() default Annotation.class;

    /**
     * This property specifies the parent that the scanner will search for.
     * <p>
     * The scanner will register all interfaces in the base package that also
     * have the specified interface class as a parent.
     * <p>
     * Note this can be combined with annotationClass.
     *
     * @return 只注册继承自markerInterface的接口
     */
    Class<?> markerInterface() default Class.class;

    /**
     * {@link HsfHttpRequestProxy} HSF接口使用HTTP请求代理类，如果没有设置此值，下面这三个字段必须设置：
     * <ul>
     * <li>{@link #restTemplateBeanName()}（可选）
     * <li>{@link #serviceVersion()}
     * <li>{@link #serverUrl()}
     * </ul>
     *
     * @return hsfHttpRequestProxy对象的Bean name
     */
    String hsfHttpRequestProxyBeanName() default "";

    /**
     * 访问Rest服务的客户端，建议此字段设置成具有连接池的单一对象
     *
     * @return restTemplate属性对象的Bean name
     * @see #hsfHttpRequestProxyBeanName()
     */
    String restTemplateBeanName() default "";

    /**
     * HSF接口的服务版本，举例：1.0.0，此字段可以使用通配符"${}"获取
     * {@link org.springframework.core.env.Environment} 中的属性
     *
     * @return HSF接口的服务版本
     * @see #hsfHttpRequestProxyBeanName()
     */
    String serviceVersion() default "";

    /**
     * HSF服务的HTTP IP地址，举例：http://ip:port，此字段可以使用通配符"${}"获取
     * {@link org.springframework.core.env.Environment} 中的属性
     *
     * @return HSF服务的HTTP IP地址
     * @see #hsfHttpRequestProxyBeanName()
     */
    String serverUrl() default "";

    /**
     * 使用自定义反序列化类来操作：HSF接口返回的值，解决某些泛型类型、特殊的需求（可选）
     *
     * @return responseBodyDeserializer属性对象的Bean
     * @see #hsfHttpRequestProxyBeanName()
     */
    String responseBodyDeserializerBeanName() default "";
}
